package de.urw.app;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;


public class XMLParser {
	public XMLObjectLinker xmlol;
	//File xml = null;
	InputStream xml = null;
	
	public XMLParser(InputStream xml, XMLObjectLinker xmlObjectLinker){
		this.xmlol = xmlObjectLinker;
		this.xml = xml;	
	}
	
	
	private int parse(Node n, int parent){
		if(n.getNodeName() == "#text"){
			return -1;
		}
		NamedNodeMap nm = n.getAttributes();
		Node nType = nm != null ? n.getAttributes().getNamedItem("type") : null;		
		boolean hasType =  (nType != null) ? true : false;
		
		String className = (hasType ? n.getAttributes().getNamedItem("type").getNodeValue() : n.getNodeName());
		
		int that = this.xmlol.createInstance(className);
				
		NamedNodeMap nodeMap = n.getAttributes();
		if(nodeMap != null)
		for (int i = 0; i < nodeMap.getLength(); i++) {
			Node node = nodeMap.item(i);
			this.xmlol.pushData(that, node.getNodeName(), node.getTextContent());
		}

		NodeList list = n.getChildNodes();
		for (int i = 0; i < list.getLength(); ++i) {
	        Node child = list.item(i);
	        int childIndex = parse(child, that);	        
	        this.xmlol.pushData(that, "child", childIndex);
		}
		
		return that;
	}
	
	
	public void parse(){
		String xmlData = "";
		BufferedReader fis = null;
		try {
			Log.d("test", "starting parse");
			fis = new BufferedReader(new InputStreamReader(this.xml, "UTF-8"));//new FileInputStream(this.xml);
			Log.d("test", "inputstream ok");
			int tempData;
			int counter = 0;
			final byte[] buf = new byte[1000];
			/*while((tempData = fis.read(buf)) > 0)
			{
				//tempData = fis.read(buf);
				//if(tempData == -1) break;
				//xmlData += (char)tempData;
				
				//tempData = fis.read(buf);
				//counter++;
				//if(tempData < 0 || counter > 10000) break;
				
				//Log.d("test", "" + counter);
				xmlData += (char)tempData;
			}*/
			
			Writer writer = new StringWriter();
			char[] buffer = new char[1024];
			
			while ((tempData = fis.read(buffer)) != -1) 
            {
                writer.write(buffer, 0, tempData);
            }
			
			xmlData = writer.toString();
			
			//log gibt viel aus:
			//Log.d("test", "stream read: " + xmlData);
		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Log.d("test", e.toString());
			e.printStackTrace();
		}finally{	
			try {
				Log.d("test", "closing stream");
				if(fis != null){
					fis.close();
				}
				Log.d("test", "stream closed");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				Log.d("test", e.toString());
				e.printStackTrace();
			}			
		}
		
		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		Document doc = null;
		
		Log.d("test", "documentbuilder initialized");
		
		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			doc = db.parse(new InputSource(new ByteArrayInputStream(xmlData.getBytes("utf-8"))));

		}catch(ParserConfigurationException pce) {
			pce.printStackTrace();
		}catch(SAXException se) {
			se.printStackTrace();
		}catch(IOException ioe) {
			ioe.printStackTrace();
		}
		
		Node root = doc.getDocumentElement();
		
		parse(root, -1);
	}

}
